package com.idrive.listener;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.telephony.PhoneStateListener;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.widget.Toast;

import com.android.internal.telephony.ITelephony;
import com.idrive.database.DatabaseUtility;
import com.idrive.database.dao.CallLogDao;
import com.idrive.database.dao.CommonDataDao;
import com.idrive.database.dto.CallLog;
import com.idrive.database.dto.CommonData;

public class IDriveCallListener extends PhoneStateListener {

	private Context context;

	public IDriveCallListener(Context context) {
		this.context = context;

	}

	public void onCallStateChanged(int state, String incomingNumber) {

		if (state == TelephonyManager.CALL_STATE_RINGING) {

			handleCall(incomingNumber);

		} else if (state == TelephonyManager.CALL_STATE_IDLE) {

			AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
			audioManager.setMode(AudioManager.MODE_IN_CALL);
			audioManager.setSpeakerphoneOn(false);

		}
	}

	private void handleCall(String incomingNumber) {
		final CommonDataDao dao = new CommonDataDao(context);
		CommonData data = dao.getCommonData();

		String option = data.getOption();

		if (DatabaseUtility.SETTINGS_OPTION_SPEAKER_PHONE.equals(option)) {
			try {
				AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
				audioManager.setMode(AudioManager.MODE_IN_CALL);
				audioManager.setSpeakerphoneOn(true);

				TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

				Class c = Class.forName(tm.getClass().getName());
				Method m = c.getDeclaredMethod("getITelephony");
				m.setAccessible(true);
				com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);

				telephonyService = (ITelephony) m.invoke(tm);
				telephonyService.silenceRinger();
				telephonyService.answerRingingCall();

			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
			}
		} else if (DatabaseUtility.SETTINGS_OPTION_SMS.equals(option)) {
			try {

				PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, new Intent("SMS_SENT"), 0);

				PendingIntent deliveredPI = PendingIntent.getBroadcast(context, 0, new Intent("SMS_DELIVERED"), 0);

				String message = data.getSms();

				SmsManager sms = SmsManager.getDefault();
				sms.sendTextMessage(incomingNumber, null, message, sentPI, deliveredPI);

				rejectCall();

				addCallLog(incomingNumber, "Rejected the call and sent recorded SMS");

			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
			}
		} else if (DatabaseUtility.SETTINGS_OPTION_VOICE_MESSAGE.equals(option)) {

			addCallLog(incomingNumber, "Rejected the call and played voice message");

		} else if (DatabaseUtility.SETTINGS_OPTION_REJECT_CALL.equals(option)) {
			try {

				rejectCall();

				addCallLog(incomingNumber, "Rejected incoming call");
			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
			}
		}
	}

	private void rejectCall() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
	        InvocationTargetException {
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

		Class c = Class.forName(tm.getClass().getName());
		Method m = c.getDeclaredMethod("getITelephony");
		m.setAccessible(true);
		com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);

		telephonyService = (ITelephony) m.invoke(tm);
		telephonyService.silenceRinger();
		telephonyService.endCall();
	}

	private void addCallLog(String number, String description) {
		Format formatter = new SimpleDateFormat("HH:mm:ss yyyy/dd/MM");
		CallLog callLog = new CallLog();
		callLog.setTelephone(number);
		callLog.setEvent(description);
		callLog.setTime(formatter.format(new Date()));

		CallLogDao dao = new CallLogDao(context);
		dao.addCallLog(callLog);
	}
}
